import cv2 as cv
import sys
import os
from python_ai.common.xcommon import *
import matplotlib.pyplot as plt
import numpy as np
import time
import datetime


def my_show_img(img, title="no title", trans=None, **kwargs):
    global spn
    spn += 1
    plt.subplot(spr, spc, spn)
    if trans is not None:
        img = trans(img)
    plt.imshow(img, **kwargs)
    plt.axis('off')
    plt.title(title)


img_dir = '../../../../large_data/CV2/lesson/Day06'
img_name = 'hammer.jpg'
# img_dir = '../../../../../large_data/pic'
# img_name = 'DSC05039.JPG'
# img_name = 'DSC05022_1.JPG'
# img_name = 'dog.jpg'
# img_name = 'dog_bird.jpg'
img_path = os.path.join(img_dir, img_name)

spr = 2
spc = 4
spn = 0
plt.figure(figsize=[14, 10])

sep('load')
img = cv.imread(img_path, cv.IMREAD_GRAYSCALE)
# img = cv.resize(img, None, fx=0.1, fy=0.1, interpolation=cv.INTER_CUBIC)
print('original shape', img.shape)
H, W = img.shape
H2 = (H - 1) // 2
W2 = (W - 1) // 2
print('ori', W, H)
my_show_img(img, 'original', cmap='gray')

# bin
ret, bin = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
my_show_img(bin, 'bin', cmap='gray')

# contours
contours, hierarchy = cv.findContours(bin, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
black = np.zeros((H, W, 3), dtype=np.uint8)
cv.drawContours(black, contours, -1, (0, 255, 0), 2)
my_show_img(black, 'contours external', lambda x: cv.cvtColor(x, cv.COLOR_BGR2RGB))

# max contour
max_len = 0
max_i = 0
eps = 1e-8
for i, c in enumerate(contours):
    c_area = cv.contourArea(c)
    c_len = cv.arcLength(c, True)
    m = cv.moments(c)
    cx = m['m10'] / (m['m00'] + eps)
    cy = m['m01'] / (m['m00'] + eps)
    print(f'#{i + 1}, area = {c_area}, arc len = {c_len}, center = {(cx, cy)}')
    if c_len > max_len:
        max_len = c_len
        max_i = i

# rect
x, y, w, h = cv.boundingRect(contours[max_i])
cv.rectangle(black, (x, y), (x + w, y + h), (0, 0, 255), 2)
my_show_img(black, 'boundingRect', lambda x: cv.cvtColor(x, cv.COLOR_BGR2RGB))

ret = cv.minEnclosingCircle(contours[max_i])
print(ret)
(x, y), r = ret
cv.circle(black, np.int32((x, y)), int(r), (0, 255, 255), 2)
my_show_img(black, 'min enclosing circle', lambda x: cv.cvtColor(x, cv.COLOR_BGR2RGB))
